package com.zhy.redis.util;

import com.zhy.redis.exception.ShareLockException;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.SystemUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * @author 随缘而愈
 * @version 1.0
 * @description redis分布式锁
 * @date 26/1/2024 下午1:25
 */
@Component
public class RedisShareLockUtil {

    @Autowired
    private RedisUtil redisUtil;

    private Long OUT_TIME = 1000L;

    /**
     * @return java.lang.Boolean
     * @author:随缘而愈
     * @date 26/1/2024 下午1:32
     * @description:必出BUG
     * @params [lockKey, requestId, time]
     */
    public Boolean lock(String lockKey, String requestId, Long time) {
        /**
         * 1.参数的校验
         * 2.加锁可以自旋
         * 3.借助redis的setnx来进行锁的设置
         */
        if (StringUtils.isBlank(lockKey) || StringUtils.isBlank(requestId) || time <= 0) {
            throw new ShareLockException("分布式锁-加锁参数配置异常");
        }
        long currentTime = System.currentTimeMillis();
        long outTime = currentTime + OUT_TIME;
        Boolean result = false;
        while (currentTime < outTime) {
            result = redisUtil.setNx(lockKey, requestId, time, TimeUnit.MILLISECONDS);
            if (result) {
                return result;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            currentTime = System.currentTimeMillis();
        }
        return result;
    }


    /**
     * @author:随缘而愈
     * @date 26/1/2024 下午2:00
     * @description: 解锁
     * @params [key, requestId]
     */
    public Boolean unLock(String key, String requestId) {
        if (StringUtils.isBlank(key) || StringUtils.isBlank(requestId)) {
            throw new ShareLockException("分布式锁-解锁参数异常");
        }
        try {
            String value = redisUtil.get(key);
            if (value.equals(requestId)) {
                redisUtil.del(key);
                return true;
            }
        } catch (Exception e) {

        }
        return false;
    }


    /**
     * @author:随缘而愈
     * @date 26/1/2024 下午2:02
     * @description: 尝试加锁
     * @params [lockKey, requestId, time]
    */
    public boolean tryLock(String lockKey, String requestId, Long time) {
        if (StringUtils.isBlank(lockKey) || StringUtils.isBlank(requestId) || time <= 0) {
            throw new ShareLockException("分布式锁-加锁参数配置异常");
        }
        return redisUtil.setNx(lockKey, requestId, time, TimeUnit.MINUTES);
    }
}
